package com.fhc.connectivity

import android.app.Application
import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject


@HiltViewModel
open class NetworkViewModel @Inject constructor(
    app : Application
) : AndroidViewModel(app) {

    protected val context
        get() = getApplication<Application>()

    private val _networkState = MutableStateFlow<ConnectionState>(ConnectionState.Unavailable)
    val networkState = _networkState.asStateFlow()
    private val connectionState: Flow<ConnectionState>
        get() = context.connectivityManager.observeConnectivityAsFlow()

    val currentConnectionState: ConnectionState
        get() = context.connectivityManager.getConnectionState()
    private fun observeConnectivity() {
        viewModelScope.launch {
            if (hasInternetConnection()) {
                _networkState.update { ConnectionState.Available }
            }
        }

        connectionState.distinctUntilChanged().onEach {it->
            Timber.i("-----State:%s",it)
            _networkState.value = it
        }.launchIn(viewModelScope)
    }

    init {
        observeConnectivity()
    }

    protected fun hasInternetConnection(): Boolean {
        val connectivityManager = getApplication<Application>().getSystemService(
            Context.CONNECTIVITY_SERVICE
        ) as ConnectivityManager
        val activeNetwork = connectivityManager.activeNetwork ?: return false
        val capabilities = connectivityManager.getNetworkCapabilities(
            activeNetwork
        ) ?: return false
        return when {
            capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
            capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
            capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
            else -> false
        }
    }


}


